#include <time.h>
#include "CdrLogger.h"
#include "XMLConfig2.h"
#include "StrOperation.h"

CdrLogger* g_CdrLogger;

CdrLogger* CdrLogger::m_CdrLogger = NULL;
OSMutex CdrLogger::m_Mutex_CdrList;
vector<cdrdata*> CdrLogger::m_CdrList;
Char* CdrLogger::m_CdrDir = NULL;

CdrLogger::CdrLogger(const Char* v_CdrDir)
{
	m_CdrDir = strdup(v_CdrDir);
	m_CdrLogger = NULL;

}

CdrLogger::~ CdrLogger()
{
	WriteCdr();
	if (m_CdrDir != NULL)
	{
		free(m_CdrDir);
	}
	if(m_Timer !=0 ) 
	{
		OSTimerTask::GetInstance()->RemoveTimer(m_Timer);
	}
}

Bool CdrLogger::Initialize()
{
	m_Timer=OSTimerTask::GetInstance()->GetTimer(this);
	return TRUE;
}

CdrLogger* CdrLogger::GetInstance()
{
	if (m_CdrLogger == NULL)
	{
//		string scdrdir = g_XMLConfig->GetCdrDir();
		string scdrdir = SConfigPara::m_CdrDir;
		if (!scdrdir.empty())
		{
			m_CdrLogger = new CdrLogger(scdrdir.c_str());
		}
	}
	return m_CdrLogger;
}

Bool CdrLogger::DelInstance()
{
	if (m_CdrLogger != NULL)
	{
		m_CdrLogger->DeleteTask();
		m_CdrLogger = NULL;
	}
	return TRUE;
}

Bool CdrLogger::AddCdrRecord(cdrdata* v_CdrData)
{
	assert(v_CdrData);
	OSMutexLocker locker(&m_Mutex_CdrList);
	m_CdrList.push_back(v_CdrData);
	return TRUE;
}

Bool CdrLogger::Run()
{
	MsgData msgData;
	OSTimerTask::GetInstance()->StartTimer(m_Timer,	10,0,this);
	while(TRUE)
	{
		while (PopMessage(&msgData) == TRUE)
		{
			switch (msgData.m_MsgID)
			{
				case RFS_MSG_NORNALQUIT:
				{
					if(OSTimerTask::GetInstance()->IsRun(m_Timer))
						OSTimerTask::GetInstance()->StopTimer(m_Timer);
					return TRUE;
				}
				case RFS_MSG_TIMEOUT:
				{
					if (msgData.m_MsgRecvObj == this)
					{
						if(OSTimerTask::GetInstance()->IsRun(m_Timer))
							OSTimerTask::GetInstance()->StopTimer(m_Timer);
						OSTimerTask::GetInstance()->StartTimer(m_Timer,	10,0,this);
						WriteCdr();
					}
				}
			}
		}
		OS::Sleep(10);
	}
	return TRUE;
}

Bool CdrLogger::WriteCdr()
{
	//get current time
	time_t tTime;
	struct tm *pTime;		
	time(&tTime);
	pTime = localtime(&tTime);
	if(NULL == pTime)
	{
		return FALSE;
	}
	Char curtime[15] = {0};
	sprintf(curtime,"%4d%02d%02d%02d%02d%02d",pTime->tm_year+1900,pTime->tm_mon+1,pTime->tm_mday,pTime->tm_hour, pTime->tm_min, pTime->tm_sec);		
	
	//cdr dir
	Char scdrdir[255] = {0};
	Char scdrfile[255] = {0};
	
	//check vector's size
	if (m_CdrList.size() == 0)
	{
		return FALSE;
	}
	
	//make dir
	//sprintf(scdrdir,"%s/%4d%02d%02d",m_CdrDir,pTime->tm_year+1900,pTime->tm_mon+1, pTime->tm_mday);
	sprintf(scdrdir,"%s",m_CdrDir);
	CStrOperate::DecodePath(scdrdir,strlen(scdrdir));
	OS::RecursiveMakeDir(scdrdir);
	
	//make cdr file
	sprintf(scdrfile,"%s/%s.cdr",scdrdir,curtime);
	CStrOperate::DecodePath(scdrfile,strlen(scdrfile));
	FILE* fp = fopen(scdrfile,"a");
	if (fp == NULL)
	{
		for (UInt32 j = 0; j < m_CdrList.size();j++)
		{
			delete m_CdrList[j];
		}
		m_CdrList.clear();
		
		return FALSE;
	}
	//write header
	Char cdrheader[1024] = "#time\turl\tserverip\tclientip\tsessionid\tuseragent\tprogramtype\tstarttime\tendtime\tplaytime\tfiletime\tsendpackets\tsendbytes\tfilesize\tqos\r\n";
	Char cdrrecord[1024] = {0};
	fwrite(cdrheader,1,strlen(cdrheader),fp);
	OSMutexLocker locker(&m_Mutex_CdrList);
	for (UInt32 i = 0; i < m_CdrList.size();i++)
	{
		sprintf(cdrrecord,"%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\r\n",
			curtime,m_CdrList[i]->url,m_CdrList[i]->serverip,m_CdrList[i]->clientip,m_CdrList[i]->sessionid,
			m_CdrList[i]->useragent,m_CdrList[i]->progtype,m_CdrList[i]->starttime,m_CdrList[i]->endtime,
			m_CdrList[i]->playtime,m_CdrList[i]->filetime,m_CdrList[i]->sendpackets,m_CdrList[i]->sendbytes,
			m_CdrList[i]->filesize,m_CdrList[i]->qos);
		fwrite(cdrrecord,1,strlen(cdrrecord),fp);
	}
	fclose(fp);
	for (UInt32 j = 0; j < m_CdrList.size();j++)
	{
		delete m_CdrList[j];
	}
	m_CdrList.clear();
	return TRUE;
}

